const data = {
  name: '小陈',
  age: 18,
  career: '前端工程师',
  info: {
    field: ['HTML', 'CSS', 'JS', 'Python'],
    framework: ['Vue', 'Jquery', 'Django'],
    student: [
      {
        name: '小辉',
        age: 12
      },
      {
        name: '小爱',
        age: 13
      }
    ]
  },
  hobby: ['ride a bike', 'sing', 'coding']
}

const arr = [
  {
    name: '小陈',
    age: 20
  },
  {
    name: '小丽',
    age: 19
  },
  {
    name: '小灰',
    age: 21
  },
  {
    name: '小群',
    age: 22
  }
];

var obj = {
  name: 'Mr.chen',
  age: 99
}

// 1. 测试一下深拷贝是否成功
if (false) {
  var newObj = deepClone(data);
  data.info.student[0].age = 20;
  console.log(data);
  console.log(newObj);
}

// 2. 测试（forEach）方法参数、返回值、内部「this」指向情况
if (false) {
  arr.forEach(function (item, index, array) {
    console.log(this); // 默认指向 window
    console.log(item, index, array);
  }, obj);

  console.log('————————————————————————————');

  arr.myforEach(function (item, index, array) {
    console.log(this);
    console.log(item, index, array);
  }, obj);
}

// 3. 测试（map）
if (false) {
  let newArr = arr.map(function (item, index, array) {
    // console.log(this); // obj
    // console.log(item, index, array);
    // item.name = 'MIUI'; // 会修改原数组中的对象数据
    // 返回的新数组由此函数内部返回值组成
    return item;
  }, obj);


  console.log('————————————————————————————');

  let newArr2 = arr.myMap(function (item, index, array) {
    // console.log(this);
    // console.log(item, index, array);
    // item.name = 'MIUI'; // 只影响返回的新数组内的对象数据（因为在对遍历元素进行了一次深拷贝）
    // return item;
  }, obj);

  // newArr[0].name = 'ok'; // 测试结果：原数组与新数组内部对象都改变了
  // newArr2[0].name = 'ok'; // 测试结果：只有新数组内部对象改变了，原数组不受其影响

  console.log(arr);
  console.log(newArr);
  console.log(newArr2);
}

// 4. 测试（filter）
if (false) {
  let newArr = arr.filter(function (item, index, array) {
    // console.log(this);
    return item.age > 19;
  }, obj);

  // newArr[0].name = 'ok'; 
  // console.log(arr);
  // console.log(newArr);

  let newArr2 = arr.myFilter(function (item, index, array) {
    // console.log(this);
    return item.age > 19;
    // return false;
  }, obj);

  console.log(newArr2);
}

// 5. 测试（every）
if (false) {
  let flag1 = arr.every(function (item, index, array) {
    // console.log(this);
    // console.log(item, index, array);
    return index;
  }, obj);
  console.log(flag1);

  console.log('————————————————————————————');

  let flag2 = arr.myEvery(function (item, index, array) {
    // console.log(this);
    // console.log(item, index, array);
    // return index;
    return false;
  }, obj);

  console.log(flag2);
}

// 6. 测试（some）
if (false) {
  const flag1 = arr.some(function (item, index, array) {
    return index;
  });

  // 空数组测试
  const flag2 = [].some(function (item, index, array) {
    return index;
  });

  console.log(flag1); // true
  console.log(flag2); // false

  console.log('————————————————————————————');

  const flag3 = arr.mySome(function (item, index, array) {
    // console.log(item);
    return item.age > 10;
  });

  const flag4 = [].mySome(function (item, index, array) {
    return index;
  });

  console.log(flag3); // true
  console.log(flag4); // false
}

// 7. 测试（reduce）
if (false) {
  const newValue1 = arr.reduce(function (prevValue, item, index, array) {
    console.log(prevValue, item.age);
    return item.age + prevValue;
  }, 0);

  console.log(newValue1);

  console.log('————————————————————————————');

  const arr2 = [];

  const newValue2 = arr.myReduce(function (prevValue, item, index, array) {
    // console.log(this);
    item.age > 15 && prevValue.push(item);
    return prevValue;
  }, arr2, obj);

  console.log(newValue2);
}

// 8. 测试（reduceRigth）
if (true) {
  const newValue1 = [1, 2, 3, 4].reduceRight(function (prevValue, item, index, array) {
    console.log(prevValue, item);
    return item + prevValue;
  }, 0);

  console.log(newValue1);

  console.log('————————————————————————————');

  const newValue2 = [1, 2, 3, 4].myReduceRight(function (prevValue, item, index, array) {
    console.log(prevValue, item);
    return item + prevValue;
  }, 0);

  console.log(newValue2);
}